/* ************ RAYTRACER.C *************************
 * 
 *   Proyecto 2: Ray Tracing Basico
 * 
 *   Prof.: 
 * 	 Francisco J. Torres Rojas PhD
 * 
 *   Autor:
 *   Andres Aguilar Umana
 *   200928927
 * 
 *   1 de Abril 2012
 * 
 ****************************************************/
#include <raytracer.h>
#include <parser.h>
#include <common.h>
#include <math.h>
#include <omp.h>
#include <string.h>

int hola;
int colocar(Interseccion *v, int b, int t)
{
	int i;
	int pivote;
	Interseccion valor_pivote;
	Interseccion temp;

	pivote = b;
	valor_pivote = v[pivote];
	for (i=b+1; i<=t; i++){
		if (v[i].t < valor_pivote.t){
			pivote++;
			temp=v[i];
			v[i]=v[pivote];
			v[pivote]=temp;

		}
	}
	temp=v[b];
	v[b]=v[pivote];
	v[pivote]=temp;
	return pivote;
} 

void Quicksort(Interseccion* v, int b, int t)
{
	int pivote;
	if(b < t){
		pivote=colocar(v, b, t);
		Quicksort(v, b, pivote-1);
		Quicksort(v, pivote+1, t);
	}
}


void iniciarRayTracing(char* file,int n, char *instArch,int inicio){

	//n = 1; file = "escena5.rt";
	Imagen imagen;
	int i,j;
	//long double Xw, Yw;
	Rayo ray;
	unsigned long total;
	int porcentaje;
	int actual;
	Color color;
	int tid,nthreads,chunk;
	Escena *escena;
	char dele;

	omp_set_num_threads(n);

	chunk = 10;

	dele = 0;
	int instante=inicio;
	//for (instante=inicio; instante <= final; instante++){
		printf("Camara %d\n",instante);
#pragma omp critical
		{
			escena = parseEscena(file,instArch,instante);
		}
		//Paralelizamos con OpenMP (utilizamos los cores del CPU)
#pragma omp parallel shared(imagen,escena,nthreads,dele,total,porcentaje,actual) private(i,j,ray,color,tid)
		{



			tid = omp_get_thread_num();

			if (tid == 0){
				// escena=NULL;

				nthreads = omp_get_num_threads();

				printf("Resolucion: %d %d\n",escena->resX,escena->resY);
				printf("Ventana: %0.2Lf %0.2Lf %0.2LF %0.2LF \n",escena->Xmin,escena->Xmax,escena->Ymin,escena->Ymax);
				printf("Antialiasing: %d\n",escena->nivelAntialiasing);
				printf("Transparencia: %d\n",escena->nivelTransparencia);
				printf("Texturas: %d\n",escena->numTexturas);
				printf("Espejo: %d\n",escena->nivelEspejo);
				printf("Luces: %d\n",escena->numLuces);
				printf("Esferas: %d\n",escena->numEsferas);
				printf("Poligonos: %d\n",escena->numPoligonos);
				printf("Cilindros: %d\n",escena->numCilindros);
				printf("Conos: %d\n",escena->numConos);
				printf("Cuadraticas: %d\n",escena->numCuadraticas);


				printf("Background: %f %f %f %f\n",escena->Background.a,escena->Background.r,escena->Background.g,escena->Background.b);
				printf("Numero de Hilos = %d\n", nthreads);
				aplastarPoligonos(escena);

				crearImagen(&imagen,escena->resX,escena->resY);

				chunk = roundl(escena->resX / (nthreads*10));
				total = escena->resX * escena->resY;
				actual = 0;

				porcentaje=1;
				dele = 1;

			}else{

				while(!dele){}

			}
			ray.ancla = escena->Ojo;
			color = escena->Background;
			printf("Hilo %d iniciando...%d chunk: %d\n",tid,dele,chunk);





#pragma omp for schedule(dynamic,chunk)
			for (i = 0; i < escena->resX; i++){
				for (j = 0; j < escena->resY; j++){
					color = ProcesarPixel(i,j,0.0,0.0,1.0,1.0,escena,ray,0,color,color,escena->nivelAntialiasing);
#pragma omp critical
					{
						PLOT(i,j,color,imagen);

						actual++;
						if (actual == total/100){

							if (porcentaje % 4 == 0)
								printf("Completado: \\ %d",++porcentaje);
							else if (porcentaje % 4 == 1)
								printf("Completado: | %d",++porcentaje);
							else if (porcentaje % 4 == 2)
								printf("Completado: / %d",++porcentaje);
							else
								printf("Completado: - %d",++porcentaje);
							printf("%%\n\033[F\033[J");
							actual = 0;
						}
					}
				}
			}
		}
		printf("Completado: %d%% \n",100);

		char str[80];
		char num[15];

		liberarEscena(escena);
		guardarImagen(imagen,"Imagenes/ima.avs");
		liberarImagen(imagen);

		strcpy(str,"convert -flip Imagenes/ima.avs Imagenes/ima");
		if (instante < 10)
			sprintf(num, "000%d.jpg", instante);
		else if (instante < 100)
			sprintf(num, "00%d.jpg", instante);
		else if (instante < 1000)
			sprintf(num, "0%d.jpg", instante);
		else
			sprintf(num, "%d.jpg", instante);

		strcat(str,num);
		system(str);//convert to jpg and rename it to imaXXXXX.jpg
		system("rm Imagenes/ima.avs");
	//}
}
Color ProcesarPixel(long double i, long double j, long double di0, long double dj0,
		long double di1, long double dj1,Escena *escena,Rayo ray, int ncolor,Color col, Color col2, int nivel){
	Color color[4];
	Color res;
	Color centro;
	int co;
	int entra = 0;
	long double diff =0;
	dj0+=0.05;
	di0+=0.05;
	dj1-=0.05;
	di1-=0.05;
	centro = RayoSubpixel(i,j,di1/2.0,dj1/2.0,escena,ray);
	if (escena->nivelAntialiasing != 0 && nivel > 0){
		if (ncolor == 1){
			color[0] = col;
			color[2] = col2;
		}else if (ncolor!=3)
			color[0] = RayoSubpixel(i,j,di0,dj0,escena,ray);

		if (ncolor == 2){
			color[1] = col;
			color[3] = col2;
		}else if (ncolor!=4)
			color[1] = RayoSubpixel(i,j,di1,dj0,escena,ray);

		if (ncolor == 3){
			color[2] = col;
			color[0] = col2;
		}else if (ncolor!=1)
			color[2] = RayoSubpixel(i,j,di1,dj1,escena,ray);

		if (ncolor == 4){
			color[3] = col;
			color[1] = col2;
		}else if (ncolor!=2)
			color[3] = RayoSubpixel(i,j,di0,dj1,escena,ray);

		res.r=0;
		res.g=0;
		res.b=0;
		for (co=0;co<4;co++){
			res.r += color[co].r;
			res.g += color[co].g;
			res.b += color[co].b;
		}
		res.r /= 4;
		res.g /= 4;
		res.b /= 4;
		entra = 0;
		for (co=0;co<4;co++){
			diff = sqrtl(
					(res.r - color[co].r)*(res.r - color[co].r)
					+(res.g - color[co].g)*(res.g - color[co].g)
					+(res.b - color[co].b)*(res.b - color[co].b)
			);
			if (diff >= 0.3){

				if (co == 0){
					color[0] = ProcesarPixel(i,j,0.0,0.0,di1/2.0,dj1/2.0,escena,ray,1,color[0],centro,nivel-1);
				}
				if (co == 1){
					color[1] = ProcesarPixel(i+di1/2.0,j,0.0,0.0,di1/2.0,dj1/2.0,escena,ray,2,color[1],centro,nivel-1);
				}
				if (co == 2)
					color[2] = ProcesarPixel(i+di1/2.0,j+dj1/2.0,0.0,0.0,di1/2.0,dj1/2.0,escena,ray,3,color[2],centro,nivel-1);
				if (co == 3)
					color[3] = ProcesarPixel(i,j+dj1/2.0,0.0,0.0,di1/2.0,dj1/2.0,escena,ray,4,color[3],centro,nivel-1);
				entra++;
			}
		}
		if (entra != 0){

			res.r=0;
			res.g=0;
			res.b=0;
			for (co=0;co<4;co++){
				res.r += color[co].r;
				res.g += color[co].g;
				res.b += color[co].b;
			}
			res.r /= 4;
			res.g /= 4;
			res.b /= 4;
		}

	}else
		res = centro;

	return res;
}

Color RayoSubpixel(long double i, long double j, long double di, long double dj,Escena *escena, Rayo ray){
	long double Xw,Yw;
	//printf("i %LF + %LF   j  %LF + %LF\n",i,di,j,dj);
	Xw = (((escena->Xmax - escena->Xmin)*(di+i))/escena->resX)+escena->Xmin;
	Yw = (((escena->Ymax - escena->Ymin)*(dj+j))/escena->resY)+escena->Ymin;
	ray.vector.dire.x = Xw - escena->Ojo.x;
	ray.vector.dire.y = Yw - escena->Ojo.y;
	ray.vector.dire.z = -escena->Ojo.z;
	Normalizar(&(ray.vector));
	return De_Que_Color(ray,escena,escena->nivelEspejo);
}

Color De_Que_Color(Rayo rayo, Escena *escena, int nivelEspejo){
	Color *color,colorEspejo, colorRes;
	Interseccion *inter;
	Objeto Q;
	Vector N,L,V,R;
	Vector UU,VV;
	Luz luz;
	int k,i,som;
	int ii,jj;
	int num,num2;
	long double I,E,dt,Fatt,LxN,intensidad;
	Interseccion *inter2;
	Rayo ray;
	long double RxV;
	hola = 0;
	num = 0;
	num2 = 0;
	inter = Primera_Interseccion(rayo,escena,&num);
	color = malloc(num*sizeof(Color));

	i = 0;
	if (inter==NULL)
		return escena->Background;  //Si es NULL no hubo interseccion
	else
	{


		color[0].a = 1.0;
		i=-1;
		do{
			i++;
			Q = inter[i].objeto;

			N = Q.Normal(&Q,inter[i].Pint);

			Normalizar(&N);

			if (PRODUCTO_PUNTO(N,rayo.vector)>0.0){
				N.dire.x *= -1.0;
				N.dire.y *= -1.0;
				N.dire.z *= -1.0;
			}

			if (Q.textura != -1){
				if (Q.tipo == CILINDRO){
					posicionTexturaCilindro(
							*((Cilindro *)Q.obj),
							((Cilindro *)Q.obj)->textura,
							inter[i].Pint,
							escena, &ii, &jj,N);
					Q.color = Textura(((Cilindro *)Q.obj)->textura, ii, jj, escena);
				}else if (Q.tipo == ESFERA){
					posicionTexturaEsfera(
							*((Esfera *)Q.obj),
							((Esfera *)Q.obj)->textura,
							inter[i].Pint,
							escena, &ii, &jj,N);
					Q.color = Textura(((Esfera *)Q.obj)->textura, ii, jj, escena);
				}
			}

			//Bump Mapping
			if (Q.bump != -1){


				if (Q.tipo == POLIGONO){
					//	printf("Hago bump %LF %LF %LF --> ",N.dire.x,N.dire.y,N.dire.z);
					posicionTexturaPoligono(*((Poligono *)Q.obj),((Poligono *)Q.obj)->bump,inter[i].Pint,escena,&ii,&jj);
					inter[i].Pint = 
							Bump(((Poligono *)Q.obj)->bump, ii, jj, escena,
									inter[i].Pint,escena->Poligonos[i].maxBump,&N,((Poligono *)Q.obj)->U
									,((Poligono *)Q.obj)->V,((Poligono *)Q.obj)->tu,((Poligono *)Q.obj)->tv);
				}else
					if (Q.tipo == CILINDRO){
						UU = PRODUCTO_CRUZ(N,((Cilindro *)Q.obj)->rayo.vector);
						VV = ((Cilindro *)Q.obj)->rayo.vector;
						posicionTexturaCilindro(*((Cilindro *)Q.obj),
								((Cilindro *)Q.obj)->bump,inter[i].Pint,
								escena,&ii,&jj,N);
						inter[i].Pint =
								Bump(((Cilindro *)Q.obj)->bump, ii, jj, escena,
										inter[i].Pint,escena->Poligonos[i].maxBump,&N,UU
										,VV,((Cilindro *)Q.obj)->tu,((Cilindro *)Q.obj)->tv);
					}else
						if (Q.tipo == ESFERA){
							UU = PRODUCTO_CRUZ(((Esfera *)Q.obj)->Norte,N);
							VV = PRODUCTO_CRUZ(UU,N);
							posicionTexturaEsfera(*((Esfera *)Q.obj),
									((Esfera *)Q.obj)->bump,
									inter[i].Pint,escena,&ii,&jj,N);
							inter[i].Pint =
									Bump(((Esfera *)Q.obj)->bump, ii, jj, escena,
											inter[i].Pint,escena->Poligonos[i].maxBump,&N,UU
											,VV,((Esfera *)Q.obj)->tu,((Esfera *)Q.obj)->tv);
						}

			}

			I = 0.0;
			E = 0.0;
			for (k=0; k<escena->numLuces; k++)
			{
				luz = escena->luces[k];

				//Vector que senala desde la interseccion hacia la Luz K
				L = CREAR_VECTOR(inter[i].Pint,luz.posicion);


				dt = Normalizar(&L);

				//Rayo hacia la luz K para detectar obstaculos
				ray.ancla = inter[i].Pint;
				ray.vector = L;



				//Detectar obstaculos para Sombras
				inter2 = Primera_Interseccion(ray,escena,&num2);
				intensidad = luz.Intensidad;

				//Translucencia!! Aca bajamos la intensidad de esa luz, hasta llegar incluso a 0
				for (som=0;som<num2;som++){
					if (inter2[som].objeto.Kt>0.0)
						intensidad *= inter2[som].objeto.Kt;
					else{
						intensidad *= 0;
						break;
					}
				}


				//Ley de Lambert
				LxN = PRODUCTO_PUNTO(L,N);

				//Si el objeto esta de frente a la fuente de luz
				if (LxN > 0.0){

					//Calculamos la intensidad de la luz dependiendo de su distancia
					Fatt = MIN(1.0, 1 / (luz.c1 + luz.c2 * dt + luz.c3 * dt * dt));



					//Vector que senala desde la interseccion hacia el ojo
					V = CREAR_VECTOR(inter[i].Pint,escena->Ojo);
					//V = (Vector){{-rayo.vector.dire.x,-rayo.vector.dire.y,-rayo.vector.dire.z}};
					Normalizar(&V);

					Normalizar(&N);
					//Vector reflejo de L con respecto a N
					R = RESTA_VECTOR(MULTIPLICA(MULTIPLICA(N,2),LxN),L);
					Normalizar(&R);

					//Aumentamos la cantidad de luz difusa en el area
					I += (LxN * Q.Kd * Fatt * intensidad);

					RxV = (PRODUCTO_PUNTO(V,R));
					//Aumentamos la cantidad de reflexion especular E
					if (RxV > 0.0)
						E += (powl(RxV,Q.Kn) * Q.Ks * intensidad * Fatt);

				}

				//}
				free(inter2);
			}
			//Cubrimos las mentiras de E
			E = MIN(1.0, E);

			I += escena->Ia * Q.Ka;// * (1-Q.Kt);

			//Cubrimos las mentiras de I
			I = MIN(1.0,I);

			color[i].a = Q.color.a;
			color[i].r = I * Q.color.r;
			color[i].g = I * Q.color.g;
			color[i].b = I * Q.color.b;

			//Especular
			color[i].r = color[i].r + E * (1.0-color[i].r);
			color[i].g = color[i].g + E * (1.0-color[i].g);
			color[i].b = color[i].b + E * (1.0-color[i].b);
			//color = inter[0].color;
			if (nivelEspejo > 0){

				V = CREAR_VECTOR(inter->Pint,escena->Ojo);
				Normalizar(&V);
				LxN = PRODUCTO_PUNTO(V,N);
				R = RESTA_VECTOR(MULTIPLICA(MULTIPLICA(N,2),LxN),V);
				Normalizar(&R);

				ray.vector = R;
				colorEspejo = De_Que_Color(ray,escena,nivelEspejo-1);

				color[i].r = color[i].r * Q.o1 + colorEspejo.r * Q.o2;
				color[i].g = color[i].g * Q.o1 + colorEspejo.g * Q.o2;
				color[i].b = color[i].b * Q.o1 + colorEspejo.b * Q.o2;
			}

		}while (Q.Kt > 0.0 && escena->nivelTransparencia>0 && i+1<num);

		if (i<=0)
			i=-1;
		else{
			color[i].r += escena->Background.r * (inter[i].objeto.o3);
			color[i].g += escena->Background.g * (inter[i].objeto.o3);
			color[i].b += escena->Background.b * (inter[i].objeto.o3);
		}
		for (;i>=0;i--){
			if (i>0){
				color[i-1].r += color[i].r * (inter[i-1].objeto.o3);
				color[i-1].g += color[i].g * (inter[i-1].objeto.o3);
				color[i-1].b += color[i].b * (inter[i-1].objeto.o3);
			}else{
				color[0].r*=(inter[0].objeto.o3);
				color[0].g*=(inter[0].objeto.o3);
				color[0].b*=(inter[0].objeto.o3);
			}
		}
	}

	free(inter);

	colorRes = color[0];
	free(color);
	return colorRes;
}

long double mod(long double a, long double b)
{
	long int result = ((long) a )/ (long) b ;
	return a - result * b;
}


Punto Bump(int text, int i, int j,Escena *escena, Punto pint, 
		long double maxBump,Vector *normal,Vector U, Vector V, long double Tu, long double Tv){

	long double HM = escena->Texturas[text].ima[MAX(0,j-1)][MAX(0,i-1)].r;
	long resX, resY;
	long double Ku, Kv;
	HM /= 255.0;
	HM *= maxBump;
	pint.x += HM * normal->dire.x;
	pint.y += HM * normal->dire.y;
	pint.z += HM * normal->dire.z;

	resX = escena->Texturas[text].resX;
	resY = escena->Texturas[text].resY;

	i = MAX(1,i-1);
	i = MIN(i,resX-2);

	j = MAX(1,j-1);
	j = MIN(j,resY-2);

	Ku = -1 * (escena->Texturas[text].ima[j][i+1].r - escena->Texturas[text].ima[j][i-1].r)/2.0;
	Ku *= Tu;


	Kv = -1 * (escena->Texturas[text].ima[j+1][i].r - escena->Texturas[text].ima[j-1][i].r)/2.0;
	Kv *= Tv;
	//printf("KU KV = %LF %LF, %d %d\n",Ku,Kv,i,j);
	(*normal).dire.x += U.dire.x * Ku + V.dire.x * Kv;
	(*normal).dire.y += U.dire.y * Ku + V.dire.y * Kv;
	(*normal).dire.z += U.dire.z * Ku + V.dire.z * Kv;
	return pint;
}

Color Textura(int text, int i, int j,Escena *escena){	

	return escena->Texturas[text].ima[MAX(0,j-1)][MAX(0,i-1)];
}

Interseccion *Primera_Interseccion(Rayo ray,Escena *escena, int *num){
	Interseccion *inter_m;
	Interseccion inter;
	long double t;
	int i,conta;
	inter_m = NULL;
	conta = 0;
	for (i=0;i<escena->numEsferas; i++){
		inter = InterEsfera(ray,&t,escena->Esferas[i],escena);
		if (t!=INFINITY && t>EPSILON){
			conta++;
			inter_m = realloc(inter_m,conta*sizeof(Interseccion));

			inter.objeto.obj = &escena->Esferas[i];
			inter.objeto.tipo = ESFERA;
			inter.objeto.Normal = NormalEsfera;
			inter.objeto.Kd = escena->Esferas[i].Kd;
			inter.objeto.Ka = escena->Esferas[i].Ka;
			inter.objeto.Ks = escena->Esferas[i].Ks;
			inter.objeto.Kn = escena->Esferas[i].Kn;
			inter.objeto.Kt = escena->Esferas[i].Kt;
			inter.objeto.o1 = escena->Esferas[i].o1;
			inter.objeto.o2 = escena->Esferas[i].o2;
			inter.objeto.o3 = escena->Esferas[i].o3;
			inter.objeto.bump = escena->Esferas[i].bump;
			inter.objeto.textura = escena->Esferas[i].textura;
			inter_m[conta-1] = inter;
		}
	}
	for (i=0;i<escena->numCilindros; i++){
		inter = InterCilindro(ray,&t,escena->Cilindros[i],escena);
		if (t!=INFINITY && t>EPSILON){
			conta++;
			inter_m = realloc(inter_m,conta*sizeof(Interseccion));
			inter.Pint.x = ray.ancla.x + t * ray.vector.dire.x;
			inter.Pint.y = ray.ancla.y + t * ray.vector.dire.y;
			inter.Pint.z = ray.ancla.z + t * ray.vector.dire.z;
			inter.objeto.obj = &escena->Cilindros[i];
			inter.objeto.tipo = CILINDRO;
			inter.objeto.Normal = NormalCilindro;
			inter.objeto.d = inter.d;
			inter.objeto.Kd = escena->Cilindros[i].Kd;
			inter.objeto.Ka = escena->Cilindros[i].Ka;
			inter.objeto.Ks = escena->Cilindros[i].Ks;
			inter.objeto.Kn = escena->Cilindros[i].Kn;
			inter.objeto.Kt = escena->Cilindros[i].Kt;
			inter.objeto.o1 = escena->Cilindros[i].o1;
			inter.objeto.o2 = escena->Cilindros[i].o2;
			inter.objeto.o3 = escena->Cilindros[i].o3;
			inter.objeto.bump = escena->Cilindros[i].bump;
			inter.objeto.textura = escena->Cilindros[i].textura;
			inter_m[conta-1] = inter;
		}
	}
	for (i=0;i<escena->numConos; i++){
		inter = InterCono(ray,&t,escena->Conos[i],escena);
		if (t!=INFINITY && t>EPSILON){
			conta++;
			inter_m = realloc(inter_m,conta*sizeof(Interseccion));
			inter.objeto.obj = &escena->Conos[i];
			inter.objeto.tipo = CONO;
			inter.objeto.Normal = NormalCono;
			inter.objeto.d = inter.d;
			inter.objeto.Kd = escena->Conos[i].Kd;
			inter.objeto.Ka = escena->Conos[i].Ka;
			inter.objeto.Ks = escena->Conos[i].Ks;
			inter.objeto.Kn = escena->Conos[i].Kn;
			inter.objeto.Kt = escena->Conos[i].Kt;
			inter.objeto.o1 = escena->Conos[i].o1;
			inter.objeto.o2 = escena->Conos[i].o2;
			inter.objeto.o3 = escena->Conos[i].o3;
			inter.objeto.bump = -1;
			inter.objeto.textura = -1;
			inter_m[conta-1] = inter;
		}
	}
	for (i=0;i<escena->numPoligonos; i++){
		int pega = 1;
		inter = InterPoligono(ray,&t,escena->Poligonos[i],escena);
		if (t!=INFINITY && t>EPSILON){
			int ii, jj;

			//Texturas normales
			if (escena->Poligonos[i].textura != -1){
				posicionTexturaPoligono(escena->Poligonos[i],escena->Poligonos[i].textura,inter.Pint,escena,&ii,&jj);
				inter.objeto.color = Textura(escena->Poligonos[i].textura,ii,jj,escena);
			}

			//Mapas de Calado
			if (escena->Poligonos[i].calado != -1){
				posicionTexturaPoligono(escena->Poligonos[i],escena->Poligonos[i].calado,inter.Pint,escena,&ii,&jj);
				pega = Calado(escena->Poligonos[i].calado,ii,jj,escena);
			}

			if (pega){
				conta++;
				inter_m = realloc(inter_m,conta*sizeof(Interseccion));
				inter.objeto.obj = &escena->Poligonos[i];
				inter.objeto.tipo = POLIGONO;
				inter.objeto.Normal = NormalPoligono;
				inter.objeto.Kd = escena->Poligonos[i].Kd;
				inter.objeto.Ka = escena->Poligonos[i].Ka;
				inter.objeto.Ks = escena->Poligonos[i].Ks;
				inter.objeto.Kn = escena->Poligonos[i].Kn;
				inter.objeto.Kt = escena->Poligonos[i].Kt;
				inter.objeto.o1 = escena->Poligonos[i].o1;
				inter.objeto.o2 = escena->Poligonos[i].o2;
				inter.objeto.o3 = escena->Poligonos[i].o3;
				inter.objeto.bump = escena->Poligonos[i].bump;
				inter.objeto.maxBump = escena->Poligonos[i].maxBump;
				inter.objeto.textura = -1;

				inter_m[conta-1] = inter;
			}
		}
	}
	for (i=0;i<escena->numCuadraticas; i++){
		inter = InterCuadratica(ray,&t,escena->Cuadraticas[i],escena);
		if (t!=INFINITY && t>EPSILON){
			conta++;
			inter_m = realloc(inter_m,conta*sizeof(Interseccion));
			inter.objeto.obj = &escena->Cuadraticas[i];
			inter.objeto.tipo = CUADRATICA;
			inter.objeto.Normal = NormalCuadratica;
			inter.objeto.Kd = escena->Cuadraticas[i].Kd;
			inter.objeto.Ka = escena->Cuadraticas[i].Ka;
			inter.objeto.Ks = escena->Cuadraticas[i].Ks;
			inter.objeto.Kn = escena->Cuadraticas[i].Kn;
			inter.objeto.Kt = escena->Cuadraticas[i].Kt;
			inter.objeto.o1 = escena->Cuadraticas[i].o1;
			inter.objeto.o2 = escena->Cuadraticas[i].o2;
			inter.objeto.o3 = escena->Cuadraticas[i].o3;
			inter.objeto.bump = -1;
			inter.objeto.textura = -1;

			inter_m[conta-1] = inter;
		}
	}


	Quicksort(inter_m,0,conta-1);
	*num = conta;
	return inter_m;
}


